home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
ppl4c10.zip
/
AMODEM.C
< prev
next >
Wrap
Text File
|
1995-02-11
|
10KB
|
296 lines
/*
** ASCII text file transfer using XON / OFF flow control protocol.
** Transfer ASCII files only. Do not attempt to transfer binary files.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "pcl4c.h"
#include "ascii.h"
#include "term_io.h"
#include "xymodem.h"
#include "amodem.h"
#include "term.h"
#include "win_io.h"
#define FALSE 0
#define TRUE !FALSE
#define ONE_SECOND 18
char lastXchar; /* last XON or XOFF sent */
int TxAscii(
int Port, /* COM port [0..3] */
char Filename[], /* filename buffer */
char Buffer[], /* data buffer */
int Length, /* size of Buffer */
int SyncFlag, /* synchronize with XON 1st */
int CharPace, /* millisecond delay after sending each character */
int TermChar, /* termination character (0x00 ==> none) */
int EchoFlag) /* do local echo if TRUE */
{int i;
int Code; /* return code */
int Handle; /* file Handle */
char LastChar; /* last character sent */
int TxChars = 0; /* # characters transmitted */
int Count; /* # bytes read from disk */
char Temp[81]; /* temporary buffer */
/* begin */
if(!FetchName(Filename)) return FALSE;
Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
if(Handle<0)
{strcpy(Temp,"Cannot open ");
strcat(Temp,Filename);
WriteMsg(Temp);
return FALSE;
}
/* do we wait for XON before starting ? */
if(SyncFlag)
{/* wait for incoming XON */
WriteMsg("ASCII: Waiting for XON");
while(1)
{if(SioBrkKey())
{WriteMsg("Canceled by USER");
return FALSE;
}
Code = CharGet(Port,ONE_SECOND);
if(Code==-1) continue;
if(Code<0) return FALSE;
if((char)Code==XON)
{WriteMsg("ASCII: initial XON received");
/* slight delay */
SioDelay(ONE_SECOND/2);
break;
}
/* received character not XON */
WinPutChar(SCR_WIN,(char)Code);
}
}
/* begin transfer */
lastXchar = XON;
WriteMsg("ASCII: Starting send");
while(SioKeyPress()) SioKeyRead();
/* clear comm port */
SioRxFlush(Port);
/* send ascii file ( stop at ^Z ) */
while(1)
{/* read next buffer from disk */
Count = read(Handle,Buffer,Length);
if(Count==0) break;
if(Count<0)
{SayError(Port,"Error on disk read");
return FALSE;
}
/* send one byte at a time */
for(i=0;i<Count;i++)
{/* User ABORTS ? */
if(UserAborts(Port)) return FALSE;
/* send byte */
LastChar = Buffer[i];
if(EchoFlag) WinPutChar(SCR_WIN,LastChar);
/* send the character */
CharPut(Port,LastChar);
if(CharPace>0) SioDelay(CharPace);
/* slight delay after each line */
if(LastChar==LF) SioDelay(4*(CharPace+1));
TxChars++;
/* ^Z marks the end of a text file */
if(LastChar==CTLZ) break;
/* check for incoming XON */
if(lastXchar==XON)
{/* check for incoming XON / XOFF */
Code = CharGet(Port,0);
if(Code>0)
{/* is byte a XOFF ? */
if((char)Code==XOFF)
{/* wait for XON */
WriteMsg("XOFF received");
lastXchar = XOFF;
/* wait for XON */
while(1)
{/* user want to quit ? */
if(SioBrkKey())
{WriteMsg("Canceled by USER");
return FALSE;
}
Code = CharGet(Port,ONE_SECOND);
if((char)Code==XON)
{WriteMsg("XON received");
lastXchar = XON;
break;
}
} /* end -- while */
} /* end -- if(XOFF) */
} /* end -- if(Code) */
} /* end -- if(XON) */
} /* end -- for(i) */
} /* end -- while */
close(Handle);
/* send termination character */
if(TermChar) CharPut(Port,(char)TermChar);
sprintf(Temp,"ASCII: %d chars sent.",TxChars);
WriteMsg(Temp);
return TRUE;
} /* end -- TxAcsii */
int RxAscii(
int Port, /* COM port [0..3] */
char Filename[], /* filename buffer */
char Buffer[], /* data buffer */
int Length, /* length of data buffer */
int RxQueSize, /* size of PCL receive buffer */
int SyncFlag, /* synchronize with XON 1st */
int TermChar, /* termination character (0x00 ==> none) */
int TimeOut, /* delay (seconds) before assuming that sender is done */
int EchoFlag) /* do local echo if TRUE */
{int i;
int Handle; /* file Handle */
int Code; /* return code */
int lo; /* receive queue low water mark */
int hi; /* receive queue high water mark */
int Index; /* buffer index */
int QueSize; /* current PCL receive queue size */
int RxChars = 0; /* # received chars */
int Count; /* # characters written to disk */
char Temp[81]; /* temporary buffer */
long LastTime; /* time last character was received */
/* begin */
lastXchar = XON;
lo = RxQueSize / 8;
hi = 5 * lo;
WriteMsg("ASCII: Starting receive ");
while(SioKeyPress()) SioKeyRead();
/* clear comm port */
/*SioRxFlush(Port);*/
/* open file passed in Filename[] for write */
if(!FetchName(Filename)) return FALSE;
Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
if(Handle<0)
{strcpy(Temp,"Cannot open ");
strcat(Temp,Filename);
WriteMsg(Temp);
return FALSE;
}
/* sync with XON 1st ? */
if(SyncFlag)
{WriteMsg("ASCII: Sending initial XON");
while(1)
{CharPut(Port,XON);
Code = CharGet(Port,ONE_SECOND);
if(Code==-1) continue;
/* transmitter is sending ! */
SioUnGetc(Port,(char)Code);
break;
}
}
/* receive text */
LastTime = SioTimer();
Index = 0;
while(1)
{/* user want to quit ? */
if(SioBrkKey())
{WriteMsg("Canceled by USER");
return FALSE;
}
/* check on PCL receive queue size */
QueSize = SioRxQue(Port);
if((QueSize>hi)&&(lastXchar==XON))
{CharPut(Port,XOFF);
lastXchar = XOFF;
WriteMsg("sending XOFF(1)");
/*sprintf(Temp,"\nQueSize=%d lo=%d hi=%d\n",QueSize,lo,hi);*/
/*WriteMsg(Temp);*/
}
if((QueSize<lo)&&(lastXchar==XOFF))
{CharPut(Port,XON);
lastXchar = XON;
WriteMsg("sending XON ");
}
/* User ABORTS ? */
if(UserAborts(Port)) return FALSE;
/* get next byte */
Code = CharGet(Port,ONE_SECOND);
if(Code==-1)
{/* done if have exceeded timeout */
if(SioTimer()-LastTime>ONE_SECOND*TimeOut)
{/* sender must be done */
Buffer[Index] = CTLZ;
break;
}
continue;
}
/* ignore 1st character if it is a 0 */
if((RxChars==0)&&((char)Code=='\0')) continue;
LastTime = SioTimer();
/* ignore XON & XOFF ( since we are the receiver ) */
if((char)Code==XON) continue;
if((char)Code==XOFF) continue;
/* received a character */
Buffer[Index++] = (char)Code;
RxChars++;
/* TermChar marks the end of a text file */
if((char)Code==TermChar)
{/* replace TermChar with ^Z */
Buffer[Index-1] = CTLZ;
RxChars++;
break;
}
if(EchoFlag) WinPutChar(SCR_WIN,(char)Code);
if(Index==Length)
{/* send XOFF to transmitter */
CharPut(Port,XOFF);
lastXchar = XOFF;
WriteMsg("sending XOFF(2)");
/* write disk file */
Count = write(Handle,Buffer,Index);
if(Count<0)
{SayError(Port,"Disk write error");
SioDelay(ONE_SECOND);
return FALSE;
}
/* send XON to sender */
CharPut(Port,XON);
lastXchar = XON;
WriteMsg("sending XON ");
Index = 0;
} /* end -- if */
} /* end -- while */
/* write any remaining data in buffer */
if(Index>0)
{Count = write(Handle,Buffer,Index);
if(Count<0)
{SayError(Port,"Disk write error");
SioDelay(ONE_SECOND);
return FALSE;
}
} /* end -- if */
close(Handle);
sprintf(Temp,"ASCII: %d chars received.",RxChars);
WriteMsg(Temp);
return TRUE;
} /* RxAscii */
int UserAborts(int Port)
{char UserChar;
/* user aborts ? */
if(SioKeyPress())
{UserChar = (char)SioKeyRead();
if(UserChar==CAN)
{TxCAN(Port);
CharPut(Port,ETX);
WriteMsg("*** Canceled by USER ***");
return TRUE;
}
/* send user char */
CharPut(Port,UserChar);
}
return FALSE;
} /* UserAborts */